using System;
using System.ComponentModel;
using System.Windows.Input;
using Projecturo.ProjecturoClient.Command;

namespace Projecturo.ProjecturoClient.ViewModel
{
    public class ViewModelBase : INotifyPropertyChanged, IDisposable
    {
        private DelegateCommand closeCommand;
        private DelegateCommand saveCommand;
        private DelegateCommand deleteCommand;
        private ViewModelReference viewModelReference = new ViewModelReference();

        public virtual string DisplayName { get; protected set; }

        public ICommand CloseCommand
        {
            get
            {
                if (this.closeCommand == null)
                    this.closeCommand = new DelegateCommand(OnCloseRequested);
                return this.closeCommand;
            }
        }


        public event EventHandler CloseRequested;

        private void OnCloseRequested()
        {
            EventHandler handler = CloseRequested;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }

        public ICommand SaveCommand
        {
            get
            {
                if (this.saveCommand == null)
                {
                    this.saveCommand = new DelegateCommand(Save, CanSave);
                }
                return this.saveCommand;
            }
        }

        protected virtual void Save()
        {
        }

        protected virtual bool CanSave()
        {
            return true;
        }

        public ICommand DeleteCommand
        {
            get
            {
                if (this.deleteCommand == null)
                {
                    this.deleteCommand = new DelegateCommand(Delete, CanDelete);
                }
                return this.deleteCommand;
            }
        }

        protected virtual void Delete()
        {
        }

        protected virtual bool CanDelete()
        {
            return true;
        }

        public event EventHandler ViewModelCreated;

        protected virtual void OnViewModelCreated()
        {
            EventHandler handler = ViewModelCreated;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }

        public virtual void SetUp()
        {
            OnViewModelCreated();
        }

        public ViewModelReference ViewModelReference
        {
            get { return this.viewModelReference; }
        }

        #region INotifyPropertyChanged Members

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if(handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region IDisposable Member

        public void Dispose()
        {
            OnDispose();
        }

        protected virtual void OnDispose()
        {
            ViewModelManager.Instance.ReleaseViewModel(this);
        }

        public virtual void SetModel(long id)
        {
        }

        public virtual void SetModel(object model)
        {
        }

        public virtual void SetParent(object parent)
        {
        }

        public virtual void Update()
        {
            ViewModelBase parentModel = ViewModelManager.Instance.GetViewModel(this.ViewModelReference.ParentViewModelId);
            if (parentModel != null)
                parentModel.Update();
        }

        #endregion
    }
}
